#!/usr/bin/perl
use strict;
use FindBin;
use JSON;
use Cwd 'abs_path';
use Getopt::Long;

use DeployUtils;
use TagentClient;

Getopt::Long::Configure("pass_through");

sub usage {
    my $pname = $FindBin::Script;

    print("Usage: $pname [--verbose 0|1]\n");
    print("              [--async 0|1] [--eofstr EOFString]\n");
    print("              [--destencoding ServerSideEndoding] [--timeout TimeoutSecs] cmd\n");
    print("\n");
    print("       --node:         Host node json\n");
    print("       --async:        execute remote cmd asynchronized\n");
    print("       --eofstr:       when command outpute match eofstr, the execute will be terminated\n");
    print("       --destencoding: Server Side encoding\n");
    print("       --timeout:      tiemout for ssh execute\n");
    print("       cmd:            command text\n");

    exit(1);
}

# windows测试target server是否可连接
# tagentexec --inspath "qqqq" -h 192.168.0.178 -p 3939 -u tagent --pass ts9012501  "dir C:"
sub main {
    my ( $isHelp, $isVerbose, $envPath, $version );
    my ( $node, $async, $cmd, $eofStr, $serverCharset, $timeOut );

    $isVerbose = 0;
    $async     = 0;
    $timeOut   = 0;

    $cmd = '';

    sub addCmd {
        my $item = shift(@_);
        $cmd = $cmd . ' ' . $item;
    }

    GetOptions(
        'h|help'         => \$isHelp,
        'v|verbose=i'    => \$isVerbose,
        'node=s'         => \$node,
        'async=i'        => \$async,
        'eofstr=s'       => \$eofStr,
        'timeout=i'      => \$timeOut,
        'destencoding=s' => \$serverCharset,
        '<>'             => \&addCmd
    );

    usage() if ( defined($isHelp) );

    my $optionError = 0;

    my $deployUtils = DeployUtils->new();

    my $nodeInfo = $deployUtils->getNodeInfo($node);
    if ( not $nodeInfo ) {
        $optionError = 1;
        print("ERROR: Execute node json not defined by environment AUTOEXEC_NODE or option --node\n");
    }

    if ( $cmd eq '' ) {
        $optionError = 1;
        print("ERROR: Must instance path with optoin --inspath.\n");
    }

    if ( $optionError == 1 ) {
        usage();
    }

    my $hasError = 0;

    my $host    = $nodeInfo->{host};
    my $port    = $nodeInfo->{protocolPort};
    my $user    = $nodeInfo->{username};
    my $pass    = $nodeInfo->{password};
    my $insId   = $nodeInfo->{resourceId};
    my $insName = $nodeInfo->{nodeName};

    if ( defined($pass) and $pass ne '' ) {
        $pass = $deployUtils->decryptPwd($pass);
    }

    my $tagent = new TagentClient( $host, $port, $pass, $timeOut, $timeOut, $serverCharset );

    my $ret = $tagent->execCmd( $user, 'echo x' );
    if ( $ret != 0 ) {
        $hasError = $hasError + $ret;
        print("ERROR: Can not connect to tagent.\n");
        return $hasError;
    }

    my $agentOsType = $tagent->{agentOsType};
    my $envLine     = '';

    my $namePath = $ENV{DEPLOY_PATH};
    my $idPath   = $ENV{DEPLOY_ID_PATH};
    if ( defined($namePath) and $namePath ne '' ) {
        my $insIdPath   = "$idPath/$insId";
        my $insNamePath = "$namePath/$insName";
        if ( $agentOsType eq 'windows' ) {
            $envLine = "set TS_INSID=$insIdPath && set TS_INSNAME=\"$insNamePath\" \&\& ";
        }
        else {
            $envLine = "export TS_INSNAME=\"$insNamePath\" || setenv TS_INSNAME \"$insNamePath\"; export TS_INSID=$insIdPath || setenv TS_INSID $insIdPath \&\& ";
        }
        $cmd = "$envLine $cmd";
    }

    print("INFO: Try to execute command by tagent...\n");
    my $exitStatus = -1;
    if ( $async == 1 ) {
        $exitStatus = $tagent->execCmdAsync( $user, $cmd, 1, $eofStr );
    }
    else {
        $exitStatus = $tagent->execCmd( $user, $cmd, 1, $eofStr );
    }

    if ( $exitStatus eq 0 ) {
        print("FINE: Tagent remote exec success.\n");
    }
    else {
        $hasError = $hasError + $exitStatus;
        print("ERROR: Tagent remote exec has error.\n");
    }

    return $hasError;
}

exit main();

